﻿using log4net;
using System;
using System.Net;
using System.Net.Sockets;
using TimeSyncUtil;

namespace TimeSyncClient
{
    public class NtpClient
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Program));

        public string NtpServerAddress { get; }
        public int NtpServerPort { get; }

        public NtpClient(string ntpServerAddress, int ntpServerPort)
        {
            NtpServerAddress = ntpServerAddress;
            NtpServerPort = ntpServerPort;
        }

        /// <summary>
        /// 尝试获取网络时间
        /// </summary>
        /// <param name="networkTime"></param>
        /// <returns></returns>
        public bool TryGetNetworkUTCTime(out DateTime networkTime)
        {
            log.Debug($"开始向服务器请求时间同步 NtpServer:{NtpServerAddress}:{NtpServerPort}");

            byte[] ntpData = new NtpSendMessage(DateTime.UtcNow, DateTime.UtcNow).BuildNTPBytes();

            // Connect to the NTP server
            IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(NtpServerAddress), NtpServerPort);
            using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            {
                socket.SendTimeout = 3000; // 3 second timeout
                socket.ReceiveTimeout = 3000;
                log.Debug($"正在连接...");
                socket.Connect(ipEndPoint);
                log.Debug($"正在发送请求...");
                socket.Send(ntpData);
                log.Debug($"正在等待返回...");
                socket.Receive(ntpData);
                log.Debug($"已收到返回...");
                socket.Close();
            }
            if (NtpResponseMessage.TryResolve(ntpData, out var responseMessage))
            {
                networkTime = responseMessage.TransmitTime;
                return true;
            }
            networkTime = DateTime.UtcNow;
            return false;
        }

    }
}
